﻿/*
 * This file is part of MonoStrategy.
 *
 * Copyright (C) 2010-2011 Christoph Husse
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: 
 *      # Christoph Husse
 * 
 * Also checkout our homepage: http://monostrategy.codeplex.com/
 */

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using MonoStrategy.RenderSystem;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization;

namespace MonoStrategy
{
    [ObfuscationAttribute(Feature = "renaming", ApplyToMembers = true)]
    [Flags]
    public enum FrameBorders
    {
        None = 0,
        Top = 1,
        Left = 8,
        Right = 16,
        Bottom = 32,
        Middle = 256,
    }

    [ObfuscationAttribute(Feature = "renaming", ApplyToMembers = true)]
    public class Frame : Control
    {
        private XMLGUIConfig.FrameEntry m_Config;

        [XmlAttribute("HiddenBorders")]
        public String HiddenBordersString
        {
            get { return HiddenBorders.ToString(); }
            set
            {
                HiddenBorders = (FrameBorders)Enum.Parse(typeof(FrameBorders), value);
            }
        }

        [XmlAttribute]
        public String Config
        {
            get
            {
                if (m_Config != null)
                    return m_Config.Name;
                else
                    return null;
            }
            set
            {
                m_Config = Program.GUIConfig.GetFrame(value);
            }
        }
        [XmlIgnore]
        public FrameBorders HiddenBorders { get; set; }

        public Frame()
            : base()
        {
            HiddenBorders = FrameBorders.None;
        }

        public Frame(Control inParent, String inFrameConfig) : base(inParent)
        {
            Config = inFrameConfig;
        }

        private void RenderTile(int inChainLeft, int inChainTop, XMLGUIConfig.TileEntry tile, double deltaX, double deltaY, double deltaWidth, double deltaHeight)
        {
            Renderer.DrawSpriteAtlas(
                    (inChainLeft + Left + tile.X + deltaX) * WidthScale,
                    (inChainTop + Top + tile.Y + deltaY) * HeightScale,
                    (tile.Width + deltaWidth) * WidthScale,
                    (tile.Height + deltaHeight) * HeightScale,
                    m_Config.ImageID,
                    Opacity,
                    tile.X,
                    tile.Y,
                    tile.Width,
                    tile.Height);
        }

        protected override void Render(int inChainLeft, int inChainTop)
        {
            var tiles = m_Config.Atlas.Tiles;
            int midWidth = Width - tiles[0].Width - tiles[1].Width - tiles[2].Width;
            int midHeight = Height - tiles[0].Height - tiles[1].Height - tiles[2].Height;
            Boolean hideTop = (HiddenBorders & FrameBorders.Top) != 0;
            Boolean hideLeft = (HiddenBorders & FrameBorders.Left) != 0;
            Boolean hideBottom = (HiddenBorders & FrameBorders.Bottom) != 0;
            Boolean hideRight = (HiddenBorders & FrameBorders.Right) != 0;
            Boolean hideMiddle = (HiddenBorders & FrameBorders.Middle) != 0;

            {
                if (!hideTop && !hideLeft) RenderTile(inChainLeft, inChainTop, tiles[0], 0, 0, 0, 0);
                if (!hideTop) RenderTile(inChainLeft, inChainTop, tiles[1], 0, 0, midWidth, 0);
                if (!hideTop && !hideRight) RenderTile(inChainLeft, inChainTop, tiles[2], midWidth, 0, 0, 0);
                if (!hideRight) RenderTile(inChainLeft, inChainTop, tiles[3], midWidth, 0, 0, midHeight);
                if (!hideRight && !hideBottom) RenderTile(inChainLeft, inChainTop, tiles[4], midWidth, midHeight, 0, 0);
                if (!hideBottom) RenderTile(inChainLeft, inChainTop, tiles[5], 0, midHeight, midWidth, 0);
                if (!hideBottom && !hideLeft) RenderTile(inChainLeft, inChainTop, tiles[6], 0, midHeight, 0, 0);
                if (!hideLeft) RenderTile(inChainLeft, inChainTop, tiles[7], 0, 0, 0, midHeight);
                if (!hideMiddle) RenderTile(inChainLeft, inChainTop, tiles[8], 0, 0, midWidth, midHeight);
            }

            base.Render(inChainLeft, inChainTop);
        }
    }
}
